package org.wdm.parsers;

import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.wdm.beans.BusDeparture;

/**
 *
 * @author iakopap
 */
public class LiveTransportParser {

    private static final String API_KEY = "5915122bb68ab108a4e151cb7faf5ed0";
    private static final String APP_ID = "5f8a3629";

    public static List<BusDeparture> parse(String stopcode, String linecode) {
        //Sending a request to placr transport api live bus service
        StringBuilder json = new StringBuilder();
        try {
            //Building the http request
            URL url = new URL("http://transportapi.com/v3/uk/bus/"
                    + "stop/" + stopcode
                    + "/live.json?"
                    + "api_key=" + API_KEY
                    + "&app_id=" + APP_ID
                    + "&group=route");

            //Reading the result of the request as json
            BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
            String readed = "";
            while ((readed = in.readLine()) != null) {
                json.append(readed);
            }
            in.close();
        } catch (IOException ioe) {
        }

        //Deserializing json into java objects using parser
        JsonParser parser = new JsonParser();

        //Getting the root element
        JsonObject root = parser.parse(json.toString()).getAsJsonObject();

        //Getting the atcocode element
        String atcocode = null;
        if (root.get("atcocode") != null) {
            atcocode = root.get("atcocode").getAsString();
        }

        //Getting the smscode element
        String smscode = null;
        if (root.get("smscode") != null) {
            smscode = root.get("smscode").getAsString();
        }

        //Getting the requestTime element
        String requestTime = null;
        if (root.get("request_time") != null) {
            requestTime = root.get("request_time").getAsString();
        }

        //Getting the departures if exists any
        List<BusDeparture> list = null;
        JsonObject departures = null;
        if (root.get("departures") != null) {
            //Initializing the list
            list = new ArrayList<BusDeparture>();
            //Getting the departures as object
            departures = root.get("departures").getAsJsonObject();

            //Looking for deaprtures for a specific bus line if exists
            JsonArray lineDepartures = null;
            if (departures.get(linecode) != null) {
                //Getting the departures as an array
                lineDepartures = departures.get(linecode).getAsJsonArray();
                Iterator<JsonElement> it = lineDepartures.iterator();
                while (it != null && it.hasNext()) {
                    //Reading the next departure element
                    JsonObject object = it.next().getAsJsonObject();

                    //Getting the transport mode
                    String mode = null;
                    if (object.get("mode") != null) {
                        mode = object.get("mode").getAsString();
                    }

                    //Getting the bus line number
                    String line = null;
                    if (object.get("line") != null) {
                        line = object.get("line").getAsString();
                    }

                    //Getting the direction description
                    String direction = null;
                    if (object.get("direction") != null) {
                        direction = object.get("direction").getAsString();
                    }

                    //Getting the operator id of the bus
                    String operator = null;
                    if (object.get("operator") != null) {
                        operator = object.get("operator").getAsString();
                    }

                    //Getting the scheduled departure time in HH:mm format
                    String aimedDepartureTime = null;
                    if (object.get("aimed_departure_time") != null) {
                        aimedDepartureTime = object.get("aimed_departure_time").getAsString();
                    }

                    //Getting the expected departure time in HH:mm format
                    String expectedDepartureTime = null;
                    if (object.get("expected_departure_time") != null) {
                        //expectedDepartureTime = object.get("expected_departure_time").getAsString();
                    }

                    //Getting the estimated departure time in HH:mm format
                    String bestDepartureEstimate = null;
                    if (object.get("best_departure_estimate") != null) {
                        bestDepartureEstimate = object.get("best_departure_estimate").getAsString();
                    }

                    //Getting the source from which received the data
                    String source = null;
                    if (object.get("source") != null) {
                        source = object.get("source").getAsString();
                    }

                    //Adding the departure into the list
                    list.add(new BusDeparture(atcocode, smscode, requestTime, mode, line, direction, operator, aimedDepartureTime, expectedDepartureTime, bestDepartureEstimate, source));
                }
            }
        }

        return list;
    }
}
